package com.uottawa.librarytest.service;

import static org.junit.Assert.*;

import java.sql.Date;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.uottawa.library.dao.LoanDAO;
import com.uottawa.library.dao.LoanPeriodDAO;
import com.uottawa.library.dao.UserDAO;
import com.uottawa.library.domain.Item;
import com.uottawa.library.domain.Loan;
import com.uottawa.library.domain.LoanPeriod;
import com.uottawa.library.domain.User;
import com.uottawa.library.service.LoanPeriodService;
import com.uottawa.library.service.LoanService;

public class LoanPeriodServiceTest {
	
	private LoanPeriodService loanPeriodService;
	private User adminUser;
	private LoanService loanService = new LoanService();
	private LoanDAO loanDAO = new LoanDAO();
	private UserDAO userDAO = new UserDAO();
	private LoanPeriodDAO loanPeriodDAO = new LoanPeriodDAO();





	@Before
	public void setup() {
		loanPeriodDAO.cleanUp();
		
		loanPeriodService = new LoanPeriodService();
		adminUser = new User(1, "admin", "0000", 0, "admin");
		userDAO.addUser(adminUser);
		
		LoanPeriod loanPeriod = new LoanPeriod(1,5);  //initial loan period duration 
		LoanPeriod renewal1 = new LoanPeriod(2,10); // first renewal
		LoanPeriod renewal2 = new LoanPeriod(3,10);// Second renewal
		LoanPeriod renewal3 = new LoanPeriod(4,10);// Third renewal
		loanPeriodService.addPeriod(loanPeriod, adminUser);
		loanPeriodService.addPeriod(renewal1, adminUser);
		loanPeriodService.addPeriod(renewal2, adminUser);
		loanPeriodService.addPeriod(renewal3, adminUser);		
		
	}
	
	@After
	public void cleanUp()
	{
		loanPeriodDAO.cleanUp();

	}
	

	@Test 
	public void addRenewal()
	{	
		int countOfRenewalsBeforeAddition = loanPeriodService.getMaxRenewals();
		LoanPeriod loanPeriod = new LoanPeriod();
		loanPeriod.setDuration(10);
		loanPeriodService.addPeriod(loanPeriod,adminUser);
		int countOfRenewalsAfterAddition =loanPeriodService.getMaxRenewals();
		assertEquals(countOfRenewalsBeforeAddition+1,countOfRenewalsAfterAddition);
		
	}

	@Test 
	public void updateRenewalDuration()
	{
		LoanPeriod loanPeriod = loanPeriodService.getLoanPeriod(1);
		loanPeriod.setDuration(10);
		loanPeriodService.setLoanPeriodDuration(loanPeriod,adminUser);
		
		int loanPeriodDurationAfterUpdate = loanPeriodService.getLoanPeriod(1).getDuration();
		assertEquals(10, loanPeriodDurationAfterUpdate);
		
		
	}
	
	@Test
	public void userRenew_lessThanMaxExtension_beforeExpiryDate()
	{	

		User regularUser = new User(5, "OkUser", "password", 0, "user");
		userDAO.addUser(regularUser);

		Item item = new Item();
		item.setItemId(1122);
	
		loanService.borrowLoanCopy(item, regularUser);
		Loan loan1 = loanDAO.getLoanByItemId(item.getItemId());

		 // renew a loan more that max number of extensions
		for (int j = 0; j < loanPeriodService.getMaxRenewals() ; j++) {
			loanService.renewLoan(loan1.getLoanId(),regularUser); // user should have the copy 
		}
	
		int NumberOfExtenstionsAfterRenewal = loanService.getNumberOfExtenstions(loan1);
		assertEquals(loanPeriodService.getMaxRenewals(),NumberOfExtenstionsAfterRenewal); 	
		
		
	}
	@Test
	public void userRenew_moreThanMaxExtension()
	{

		User regularUser = new User(4, "userNeedsMoreExtension", "password", 0, "user");
		userDAO.addUser(regularUser);

		Item item = new Item();
		item.setItemId(1020);
		
		loanService.borrowLoanCopy(item, regularUser);
		Loan loan1 = loanDAO.getLoanByItemId(item.getItemId());

		 // renew a loan more that max number of extensions
		for (int j = 0; j < loanPeriodService.getMaxRenewals() +3 ; j++) {
			loanService.renewLoan(loan1.getLoanId(),regularUser); // user should have the copy 
		}
	
		int NumberOfExtenstionsAfterRenewal = loanService.getNumberOfExtenstions(loan1);
		assertEquals(loanPeriodService.getMaxRenewals(),NumberOfExtenstionsAfterRenewal); 	
		
		
	}
	@Test
	public void userRenew_afterExpiryDate()
	{	
		User regularUser = new User(6, "UserWithExpiryDate", "password", 0, "user");
		userDAO.addUser(regularUser);

		Item item = new Item();
		item.setItemId(1020);
		loanService.borrowLoanCopy(item, regularUser);
		
		Loan loan1 = loanDAO.getLoanByItemId(item.getItemId());
		int NumberOfExtenstionsBeforeRenewal = loanService.getNumberOfExtenstions(loan1);

		java.util.Date currentDate = Calendar.getInstance().getTime(); // current date of now 
		currentDate.setHours(currentDate.getHours() - 3 );
		loan1.setExpiryDate(new java.sql.Timestamp(currentDate.getTime()));
		loanDAO.updateLoan(loan1);

		loanService.renewLoan(loan1.getLoanId(), regularUser);
		
		int NumberOfExtenstionsAfterRenewal = loanService.getNumberOfExtenstions(loan1);
		assertEquals(NumberOfExtenstionsBeforeRenewal,NumberOfExtenstionsAfterRenewal); 	
		
		
	}
	@Test
	public void userRenew_asExpiryDate()
	{	
		User regularUser = new User(6, "UserWithExpiryDate", "password", 0, "user");
		userDAO.addUser(regularUser);

		Item item = new Item();
		item.setItemId(1020);
		loanService.borrowLoanCopy(item, regularUser);
		
		Loan loan1 = loanDAO.getLoanByItemId(item.getItemId());
		int NumberOfExtenstionsBeforeRenewal = loanService.getNumberOfExtenstions(loan1);

		java.util.Date currentDate = Calendar.getInstance().getTime(); // current date of now 
		currentDate.setSeconds(currentDate.getSeconds() - 2 );
		loan1.setExpiryDate(new java.sql.Timestamp(currentDate.getTime()));
		loanDAO.updateLoan(loan1);

		loanService.renewLoan(loan1.getLoanId(), regularUser);
		
		int NumberOfExtenstionsAfterRenewal = loanService.getNumberOfExtenstions(loan1);
		assertEquals(NumberOfExtenstionsBeforeRenewal,NumberOfExtenstionsAfterRenewal); 	
		
		
	}
	
	@Test
	public void userRenewloanWhileOneLoanExpired(){
		
		User regularUser = new User(7, "UserWithOneExpiryDate", "password", 0, "user");
		userDAO.addUser(regularUser);

		Item item1 = new Item();
		item1.setItemId(7654);
		loanService.borrowLoanCopy(item1, regularUser);
		Loan loan1 = loanDAO.getLoanByItemId(item1.getItemId());

		Item item2 = new Item();
		item2.setItemId(5342);
		loanService.borrowLoanCopy(item2, regularUser);
		Loan loan2 = loanDAO.getLoanByItemId(item1.getItemId());

		// Start, modify the expiry date of the first loan,  
		java.util.Date currentDate = Calendar.getInstance().getTime(); // current date of now 
		currentDate.setHours(currentDate.getHours() - 3 );
		loan1.setExpiryDate(new java.sql.Timestamp(currentDate.getTime()));
		loanDAO.updateLoan(loan1);
		// End
		
		
		//try to do renewal for the second loan 
		int NumberOfExtenstionsBeforeRenewal = loanService.getNumberOfExtenstions(loan2);
		loanService.renewLoan(loan2.getLoanId(), regularUser);
		int NumberOfExtenstionsAfterRenewal = loanService.getNumberOfExtenstions(loan2);
		
		assertEquals(NumberOfExtenstionsBeforeRenewal,NumberOfExtenstionsAfterRenewal); 
	
	}


}
